package top.zhangjianyong.blog.response;

import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import top.zhangjianyong.blog.enums.RespCode;
import top.zhangjianyong.blog.exception.ApiException;

/**
 * 全局异常处理类
 *
 * @author zhangjianyong
 * @since 2024/7/19 下午1:59
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

  /*接口异常*/
  @ExceptionHandler(ApiException.class)
  public ResponseEntity<ApiResponse> handle(ApiException e) {
    log.error(e.getMessage(), e);
    return new ResponseEntity<>(ApiResponse.fail(e.getRespCode()), HttpStatus.OK);
  }

  /*参数验证错误异常处理*/
  @ExceptionHandler(MethodArgumentNotValidException.class)
  public ResponseEntity<ApiResponse> handle(MethodArgumentNotValidException e) {
    log.error(e.getMessage(), e);
    String message =
        e.getBindingResult().getAllErrors().stream()
            .map(DefaultMessageSourceResolvable::getDefaultMessage)
            .collect(Collectors.joining(";"));
    return new ResponseEntity<>(ApiResponse.fail(message), HttpStatus.OK);
  }

  /*请求地址错误异常*/
  @ExceptionHandler(NoResourceFoundException.class)
  public ResponseEntity<ApiResponse> handle(NoResourceFoundException e) {
    log.error(e.getMessage(), e);
    String resourcePath = e.getResourcePath();
    return new ResponseEntity<>(ApiResponse.fail("请求地址错误：" + resourcePath), HttpStatus.OK);
  }

  @ExceptionHandler(MyBatisSystemException.class)
  public ResponseEntity<ApiResponse> handle(MyBatisSystemException e) {
    log.error(e.getMessage(), e);
    return new ResponseEntity<>(
        ApiResponse.fail(RespCode.ERROR_MYBATIS), HttpStatus.INTERNAL_SERVER_ERROR);
  }

  @ExceptionHandler(Exception.class)
  public ResponseEntity<ApiResponse> handle(Exception e) {
    // 你可以在这里记录日志、发送通知等
    log.error(e.getMessage(), e);
    // 返回一个通用的错误响应
    return new ResponseEntity<>(ApiResponse.fail(e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
  }
}
